package com.climber.android.commonsdk.util

import android.content.Context
import android.text.TextUtils
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.climber.android.commonsdk.api.APIError
import com.climber.android.commonsdk.api.APIErrorToast
import com.climber.android.commonsdk.event.BusProvider
import com.climber.android.commonsdk.event.CommonBusEvent
import com.climber.android.commonsdk.event.StatusDialogType
import com.climber.android.commonsdk.util.date.BaseDate
import com.climber.android.commonsdk.util.date.Date
import io.ganguo.library.mvp.util.GsonUtils
import io.ganguo.library.mvp.util.KeyboardUtils
import io.ganguo.library.mvp.util.StringUtils
import io.ganguo.library.mvp.util.ToastHelper
import io.reactivex.Observable
import okhttp3.MediaType
import okhttp3.RequestBody
import java.text.NumberFormat
import java.util.concurrent.TimeUnit

/**
 * Created by Mikes at 2019-06-26 14:37
 * 基础工具类，供其他组件调用
 */
object APIDataHelper {
    const val TEXT_PLACEHOLDER = "-"

    fun sendShowErrorMessageEvent(msg: String? = null, msgId: Int? = null){
        sendShowMessageEvent(StatusDialogType.error, msg = msg, msgId = msgId)
    }

    fun sendShowInfoMessageEvent(msg: String? = null, msgId: Int? = null){
        sendShowMessageEvent(StatusDialogType.info, msg = msg, msgId = msgId)
    }

    fun sendShowSuccessMessageEvent(msg: String? = null, msgId: Int? = null){
        sendShowMessageEvent(StatusDialogType.success, msg = msg, msgId = msgId)
    }

    private fun sendShowMessageEvent(type: StatusDialogType, msg: String? = null, msgId: Int? = null){
        BusProvider.getInstance().post(CommonBusEvent.ShowMessageEvent(type, msg = msg, msgId = msgId))
    }

    @JvmStatic
    fun getNonNullString(str : CharSequence?, defaultStr : String = "") : String{
        if(TextUtils.isEmpty(str)) return defaultStr

        return str.toString()
    }

    /**
     * do not parse responseError.fieldData != null case
     */
    fun showAPIError(apiError: APIError) {
        try{
            when (apiError) {
                is APIError.ServerError -> {
                    ToastHelper.toastMessage(apiError.errorMsg)
                }
                is APIError.ConnectFailedException ->{
                    BusProvider.getInstance().post(CommonBusEvent.ShowAPIErrorToastEvent(APIErrorToast.TimeoutError))
                }
            }
        } catch (e : Exception){
            BusProvider.getInstance().post(CommonBusEvent.ShowAPIErrorToastEvent(APIErrorToast.UnknownError))
        }
    }

    fun timestampFor10ByteTo13Byte(value : Long?) : Long{
        if(value == null) return 0L
        return value * 1000
    }

    fun timestampFor13ByteTo10Byte(value : Long?) : Long{
        if(value == null) return 0L
        return value / 1000
    }

    fun generateFormatTimeStamp(value : Long?) : String{
        return if(value != null){
            Date.FORMATTER_DATE_TIME.format(BaseDate(value))
        } else{
            TEXT_PLACEHOLDER
        }
    }

    // 已经有百分比。 e.g. percent == 20 means output should be 20%
    fun generatePercent0to100String(percent0to100: Double?, digits: Int = 2, isForChange: Boolean = false): String {
        val percentageFormatter = NumberFormat.getPercentInstance()
        percentageFormatter.maximumFractionDigits = digits
        percentageFormatter.minimumFractionDigits = digits

        return if (percent0to100 != null) {
            if (isForChange) {
                if (percent0to100 >= 0) {
                    "+${percentageFormatter.format(percent0to100 / 100)}"
                } else {
                    percentageFormatter.format(percent0to100 / 100)
                }
            } else {
                percentageFormatter.format(percent0to100 / 100)
            }
        } else {
            TEXT_PLACEHOLDER
        }
    }

    //没有百分比。`percent` is 0.0~1.0; e.g. percent == 0.2 means output should be 20%
    fun generatePercent0To1String(percent0to1: Double?, digits: Int = 2, isForChange: Boolean = false): String {
        val percentageFormatter = NumberFormat.getPercentInstance()
        percentageFormatter.maximumFractionDigits = digits
        percentageFormatter.minimumFractionDigits = digits

        return if (percent0to1 != null) {
            if (isForChange) {
                if (percent0to1 >= 0) {
                    "+${percentageFormatter.format(percent0to1)}"
                } else {
                    percentageFormatter.format(percent0to1)
                }
            } else {
                percentageFormatter.format(percent0to1)
            }
        } else {
            TEXT_PLACEHOLDER
        }
    }

    fun generatePriceString(value: Double?, digits: Int = 2, isForChange: Boolean = false): String {
        val priceFormatter = NumberFormat.getNumberInstance()
        priceFormatter.maximumFractionDigits = digits
        priceFormatter.minimumFractionDigits = digits

        return if (value != null) {
            if (isForChange) {
                if (value >= 0) {
                    "+${priceFormatter.format(value)}"
                } else {
                    priceFormatter.format(value)
                }
            } else {
                priceFormatter.format(value)
            }
        } else {
            TEXT_PLACEHOLDER
        }
    }

    fun generateNumberString(value: Long?, digits: Int = 0, isForChange: Boolean = false): String {
        val priceFormatter = NumberFormat.getNumberInstance()
        priceFormatter.maximumFractionDigits = digits
        priceFormatter.minimumFractionDigits = digits

        return if (value != null) {
            if (isForChange) {
                if (value >= 0) {
                    "+${priceFormatter.format(value)}"
                } else {
                    priceFormatter.format(value)
                }
            } else {
                priceFormatter.format(value)
            }
        } else {
            TEXT_PLACEHOLDER
        }
    }

    @JvmStatic
    fun generateRequestBody(params: Map<String, Any>): RequestBody =
            RequestBody.create(MediaType.parse("application/json"), GsonUtils.toJson(params))

    /**
     * 内容不足一瓶展示时，不能上拉加载更多
     */
    fun canPullUpToLoadMore(view: RecyclerView): Boolean {
        val layoutManager = view.layoutManager
        return when (layoutManager) {
            is GridLayoutManager -> {
                val visibleItemCount = layoutManager.childCount
                val totalItemCount = layoutManager.itemCount
                visibleItemCount != totalItemCount
            }
            is LinearLayoutManager -> {
                val visibleItemCount = layoutManager.childCount
                val totalItemCount = layoutManager.itemCount
                visibleItemCount != totalItemCount
            }
            else -> view.canScrollVertically(1)
        }
    }

    fun checkPhoneNumberValid(mobileNumber: String): Boolean = mobileNumber != "" && StringUtils.isOnlyNumber(mobileNumber)

    fun createIMESearchClickObservable(context: Context, queryEditText: EditText): Observable<String> {
        val imeSearchClickObservable = Observable.create<String> { emitter ->
            queryEditText.setOnEditorActionListener { v, actionId, event ->
                if (actionId == EditorInfo.IME_ACTION_SEARCH) {
                    KeyboardUtils.hideSoftInput(context, queryEditText)
                    emitter.onNext(queryEditText.text.toString())
                }
                false
            }

            emitter.setCancellable { queryEditText.setOnEditorActionListener(null) }
        }

        return imeSearchClickObservable
                .filter { keyword -> keyword.trim { it <= ' ' }.isNotEmpty() }
                .debounce(300, TimeUnit.MILLISECONDS)
    }
}